<script setup lang='ts' name="protocol-management-add">
import type { OptionsType, PlusFormGroupRow } from 'plus-pro-components'
import type { VxeGridProps, VxeTableInstance } from 'vxe-table'

import { useAddAgreement, useGetAgreementOptions, useGetProductCategoryOptions, useGetSupplierLabelOptions } from '@fl/api/supplier'
import { SearchTable } from '@fl/components'
import FlUpload from '@fl/components/fl-upload.vue'
import { useUserStore } from '@fl/store/modules/user'
import { treeFindLabel } from '@fl/utils/tree'
import { ElMessage } from 'element-plus'
import { cloneDeep } from 'lodash-es'

import { AGREEMENT_TYPE } from './constant'
import ImportGoods from './import-goods.vue'

const router = useRouter()
const userStore = useUserStore()

const showImportGoods = ref(false)

const initialState = {
    agreementAttachmentList: [],
    validPeriod: [],
} as any
const state = ref(cloneDeep(initialState))

const getAgreementOptionsParams = computed(() => ({ agreementType: 1, partyAId: state.value.partyAId }))
const isProjectContract = computed(() => Number(state.value.agreementType) === 2)
const agreementId = ref<string | undefined>(undefined)
const categoryId = ref<string | undefined>(undefined)

const { data: productCategoryOptionsData, isLoading: isGetProductCategoryOptionsLoading } = useGetProductCategoryOptions()
const { data: supplierLabelOptionsData, isLoading: isGetSupplierLabelOptionsLoading } = useGetSupplierLabelOptions()
const { data: agreementOptionsData, isLoading: _isGetAgreementOptionsLoading } = useGetAgreementOptions(getAgreementOptionsParams)
const { isPending: isAddAgreementPending, mutate: addAgreement } = useAddAgreement()

// #region Form
const formRef = ref()
const isFormLoading = computed(() => isGetProductCategoryOptionsLoading.value || isGetSupplierLabelOptionsLoading.value)
const isSubmitLoading = computed(() => isAddAgreementPending.value)

const group: PlusFormGroupRow[] = [
    {
        columns: [
            {
                colProps: {
                    span: 8,
                },
                label: '协议名称',
                prop: 'agreementName',
                valueType: 'copy',
            },
            {
                colProps: {
                    span: 8,
                },
                label: '协议类目',
                options: productCategoryOptionsData as OptionsType,
                prop: 'categoryId',
                valueType: 'select',
            },
            {
                colProps: {
                    span: 8,
                },
                fieldProps: {
                    endPlaceholder: '请选择结束时间',
                    startPlaceholder: '请选择开始时间',
                    type: 'daterange',
                    valueFormat: 'YYYY-MM-DD',
                },
                label: '协议有效期',
                prop: 'validPeriod',
                valueType: 'date-picker',
            },
            {
                colProps: {
                    span: 8,
                },
                label: '协议类型',
                options: AGREEMENT_TYPE,
                prop: 'agreementType',
                valueType: 'select',
            },
            {
                colProps: {
                    span: 8,
                },
                hideInForm: computed(() => !isProjectContract.value),
                label: '合同金额',
                prop: 'contractPrice',
                valueType: 'copy',
            },
        ],
        title: '基础信息',
    },
    {
        columns: [
            {
                colProps: {
                    span: 8,
                },
                label: '甲方',
                options: supplierLabelOptionsData as OptionsType,
                prop: 'partyAId',
                valueType: 'select',
            },
            {
                colProps: {
                    span: 8,
                },
                label: '乙方',
                prop: 'partyB',
                valueType: 'text',
            },
            {
                colProps: {
                    span: 8,
                },
                hideInForm: computed(() => !isProjectContract.value),
                label: '关联协议',
                options: agreementOptionsData as OptionsType,
                prop: 'relationAgreementId',
                valueType: 'select',
            },
            {
                label: '附件上传',
                prop: 'agreementAttachmentList',
            },
        ],
        title: '协议主体',
    },
    {
        columns: [
            {
                hasLabel: false,
                prop: 'productList',
            },
        ],
        title: '商品清单',
    },
]

const rules = computed(() => ({
    agreementName: [
        {
            message: '请输入协议名称',
            required: true,
            trigger: 'change',
        },
    ],
    agreementType: [
        {
            message: '请选择协议类型',
            required: true,
            trigger: 'change',
        },
    ],
    categoryId: [
        {
            message: '请选择协议类目',
            required: true,
            trigger: 'change',
        },
    ],
    partyAId: [
        {
            message: '请选择甲方',
            required: true,
            trigger: 'change',
        },
    ],
    relationAgreementId: [
        {
            message: '请选择关联协议',
            required: isProjectContract.value,
            trigger: 'change',
        },
    ],
    validPeriod: [
        {
            message: '请选择协议有效期',
            required: true,
            trigger: 'change',
        },
    ],
}))
// #endregion

// #region Table
const tableRef = ref<VxeTableInstance>()
const tableData = ref<any[]>([])

const gridOptions = computed<VxeGridProps>(() => ({
    columns: [
        { field: 'productName', title: '产品名称', width: 200 },
        { field: 'skuName', title: '商品名称' },
        { field: 'brand', title: '品牌' },
        { field: 'model', title: '型号' },
        { field: 'unit', title: '单位', width: 100 },
        { field: 'oldPrice', formatter: formatPrice, title: '协议价格', visible: isProjectContract.value, width: 100 },
        {
            editRender: { attrs: { type: 'number' }, name: 'input', placeholder: '请输入价格(不含税)' },
            field: 'sellingPrice',
            slots: { default: 'selling_price' },
            title: '价格(不含税)',
            width: 180,
        },
        {
            editRender: { attrs: { type: 'number' }, name: 'input', placeholder: '请输入价格(含税)' },
            field: 'agreementPrice',
            slots: { default: 'agreement_price' },
            title: '价格(含税)',
            width: 180,
        },
        {
            editRender: { attrs: { type: 'number' }, name: 'input', placeholder: '请输入采购数量' },
            field: 'count',
            slots: { default: 'count' },
            title: '采购数量',
            visible: isProjectContract.value,
            width: 160,
        },
        { fixed: 'right', slots: { default: 'operation' }, title: '操作', width: 100 },
    ],
    editConfig: {
        mode: 'cell',
        trigger: 'click',
    },
    editRules: {
        agreementPrice: [
            { message: '必须填写价格(含税)', required: true, trigger: 'change' },
        ],
        count: [
            { message: '必须填写采购数量', required: isProjectContract.value, trigger: 'change' },
        ],
        sellingPrice: [
            { message: '必须填写价格(不含税)', required: true, trigger: 'change' },
        ],
    },
    validConfig: {
        autoPos: false,
        msgMode: 'full',
    },
}))

function formatPrice({ cellValue }) {
    return (!cellValue || Number.isNaN(cellValue)) ? '' : `¥${cellValue.toFixed(2)}`
}
// #endregion

// #region UI Listener
function onImportGoodsBtnClick() {
    if (isProjectContract.value) {
        if (state.value.relationAgreementId) {
            agreementId.value = state.value.relationAgreementId
            categoryId.value = undefined
        }
        else {
            ElMessage.warning('请先选择关联协议')
            return
        }
    }
    else {
        if (state.value.categoryId) {
            agreementId.value = undefined
            categoryId.value = state.value.categoryId
        }
        else {
            ElMessage.warning('请先选择协议类目')
            return
        }
    }
    showImportGoods.value = true
}

function onRemoveBtnClick(row: any) {
    const $table = (tableRef.value as any)?.tableInstance
    if ($table) {
        $table.remove(row)
    }
}

function onBackBtnClick() {
    router.back()
}

function onSaveBtnClick() {
    submitAgreement('1')
}

async function onSubmitBtnClick() {
    const $table = (tableRef.value as any)?.tableInstance
    if ($table) {
        const errMap = await $table.fullValidate(true)
        if (errMap) {
            return
        }
    }
    formRef.value.handleSubmit()
}

function submit() {
    submitAgreement('2')
}

function submitAgreement(status: string) {
    const data = cloneDeep(state.value)
    const $table = (tableRef.value as any)?.tableInstance
    const { tableData } = $table.getTableData()
    const params = {
        ...data,
        agreementAttachment: JSON.stringify(data.agreementAttachmentList?.[0] || {}),
        agreementAttachmentList: undefined,
        agreementState: status,
        categoryName: treeFindLabel({ targetValue: data.categoryId, treeData: productCategoryOptionsData.value }),
        endDate: data.validPeriod?.[1],
        partyA: treeFindLabel({ targetValue: data.partyAId, treeData: supplierLabelOptionsData.value! }),
        productList: tableData,
        relationAgreementName: treeFindLabel({ targetValue: data.relationAgreementId, treeData: agreementOptionsData.value! }),
        startDate: data.validPeriod?.[0],
    }
    addAgreement(params, {
        onSuccess() {
            ElMessage.success('操作成功')
            router.back()
        },
    })
}

function confirm(val: any[]) {
    tableData.value = val.map((item: any) => ({
        agreementPrice: '',
        attribute: item.attribute,
        brand: item.brandName,
        category: item.categoryPath,
        model: item.productModel,
        oldPrice: item.oldPrice,
        productCode: item.productNo,
        productId: item.productId,
        productName: item.productName,
        skuId: item.skuId,
        skuName: item.skuName,
        skuUrl: item.productImage,
        unit: item.productUnit,
    }))
}
// #endregion

onMounted(() => {
    Object.assign(state.value, {
        partyB: userStore.getUserInfo?.enterpriseName,
        partyBId: userStore.getUserInfo?.enterpriseId,
    })
})

watch(() => [state.value.categoryId, state.value.agreementType], () => {
    tableData.value = []
})

watch(() => state.value.partyAId, (_newValue, _oldValue) => {
    if (isProjectContract.value) {
        state.value.relationAgreementId = undefined
    }
})

watchEffect(() => {
    if (isProjectContract.value) {
        const $table = (tableRef.value as any)?.tableInstance
        const { tableData } = $table.getTableData()
        state.value.contractPrice = tableData.reduce((acc: number, cur: any) => {
            if (cur.agreementPrice && !Number.isNaN(cur.agreementPrice) && cur.count && !Number.isNaN(cur.count)) {
                return acc + cur.agreementPrice * cur.count
            }
            return acc
        }, 0).toFixed(2)
    }
    else {
        state.value.contractPrice = undefined
        state.value.relationAgreementId = undefined
    }
})
</script>

<template>
    <el-card shadow="never">
        <el-skeleton v-if="isFormLoading"
                     animated
        />

        <PlusForm v-else
                  ref="formRef"
                  v-model="state"
                  :group="group"
                  :label-width="100"
                  :rules="rules"
                  :row-props="{ gutter: 40 }"
                  @submit="submit"
        >
            <template #plus-field-agreementAttachmentList>
                <FlUpload v-model="state.agreementAttachmentList"
                          list-type="text"
                          accept=".png,.jpg,.jpeg,.docx,.xlsx,.pdf"
                          tips
                />
            </template>

            <template #plus-field-productList>
                <div class="w-full">
                    <SearchTable v-bind="gridOptions"
                                 ref="tableRef"
                                 :loading="gridOptions.loading"
                                 :data="tableData"
                    >
                        <template #operation="{ row }">
                            <el-button v-if="row.agreementState !== 7"
                                       text
                                       type="danger"
                                       class="!p-4"
                                       @click="onRemoveBtnClick(row)"
                            >
                                删除
                            </el-button>
                        </template>

                        <template #selling_price="{ row }">
                            <el-input v-model="row.sellingPrice"
                                      placeholder="请输入价格(不含税)"
                                      type="number"
                            />
                        </template>

                        <template #agreement_price="{ row }">
                            <el-input v-model="row.agreementPrice"
                                      placeholder="请输入价格(含税)"
                                      type="number"
                            />
                        </template>

                        <template #count="{ row }">
                            <el-input v-model="row.count"
                                      placeholder="请输入采购数量"
                                      type="number"
                            />
                        </template>

                        <template #toolbar_buttons>
                            <el-space>
                                <el-button type="primary"
                                           @click="onImportGoodsBtnClick"
                                >
                                    <div class="i-ic:baseline-add size-16" />
                                    引入商品
                                </el-button>

                                <!-- <el-button>
                                    <div class="i-ic:baseline-add size-16" />
                                    新增商品
                                </el-button> -->
                            </el-space>
                        </template>
                    </SearchTable>
                </div>
            </template>

            <template #footer>
                <div class="mx-auto">
                    <el-button @click="onBackBtnClick">
                        取消
                    </el-button>

                    <el-button type="primary"
                               @click="onSaveBtnClick"
                    >
                        保存
                    </el-button>

                    <el-button type="primary"
                               :loading="isSubmitLoading"
                               @click="onSubmitBtnClick"
                    >
                        提交
                    </el-button>
                </div>
            </template>
        </PlusForm>
    </el-card>

    <!-- 引入商品弹框 -->
    <ImportGoods :key="String(showImportGoods)"
                 v-model:visible="showImportGoods"
                 :agreement-id="agreementId"
                 :category-id="categoryId"
                 @confirm="confirm"
    />
</template>

<style lang="less" scoped>
.info-title {
    font-size: 16px;
    font-weight: 600;
    line-height: 60px;
    border-bottom: 1px solid #eaebef;
    margin-bottom: 22px;
}
</style>
